package com.ccx.coachsite.util;



import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;

public class SignedReader {

	private static final String TAG = "SignedReader";

	public SignedReader() {
	}

	public boolean compareSigned(Context context, String packageName,
			String path) {
		PackageManager pm = context.getPackageManager();

		Signature[] sig1 = getSignatureByPackageName(pm, packageName);
		if(null == sig1){
			return false;
		}
		
		Signature[] sig2 = getSignatureByPath(pm, path);

		if (sig2 != null) {
			return doCompareSigned(sig1[0], sig2[0]);
		} else {
			return false;
		}
	}
	
	public String getPackageName(Context context,File apk){
	    PackageInfo packageInfo = context.getPackageManager().getPackageArchiveInfo(apk
			    .getAbsolutePath(), PackageManager.GET_ACTIVITIES);
	    if(packageInfo == null){
	    	return "";
	    }
	   return packageInfo.packageName;
	}

	private boolean doCompareSigned(Signature sig1, Signature sig2) {
		return sig1.hashCode() == sig2.hashCode();
	}

	private Signature[] getSignatureByPackageName(PackageManager pm,
			String packageName) {
		Signature[] sigs = null;
		try {
			PackageInfo pkgInfo = pm.getPackageInfo(packageName,
					PackageManager.GET_SIGNATURES);
			sigs = pkgInfo.signatures;
			LogUtil.d(TAG, packageName+" signatures found");
		} catch (PackageManager.NameNotFoundException e) {
			LogUtil.e(TAG, "Package " + packageName + " not found");
		}
		return sigs;
	}

	private Signature[] getSignatureByPath(PackageManager pm, String path) {
		File apk = new File(path);
		if (apk.exists() && apk.isFile()) {
			return loadSignatures(apk);
		}
		return null;
	}

	private Signature[] loadSignatures(File apkPath) {

		Signature[] sigs = null;

		Certificate[] certs = loadCertificates(apkPath);

		try {
			sigs = convert(certs);
		} catch (CertificateEncodingException e) {
			e.printStackTrace();
		}

		if (sigs == null) {
			LogUtil.e(TAG, "Package " + apkPath.getAbsolutePath()
					+ " not found");
		} else {
			LogUtil.d(TAG, apkPath.getName() + " signatures found");
		}

		return sigs;
	}

	private Certificate[] loadCertificates(File apkPath) {
		try {
			byte[] readBuffer = new byte[8192];

			JarFile jarFile = new JarFile(apkPath);
			JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
			InputStream is = new BufferedInputStream(jarFile.getInputStream(je));
			while (is.read(readBuffer, 0, readBuffer.length) != -1) {
			}
			
			is.close();
			return je != null ? je.getCertificates() : null;

		} catch (IOException e) {
			LogUtil.w(TAG, "Exception reading");
		} catch (RuntimeException e) {
			LogUtil.w(TAG, "Exception reading");
		}

		return null;
	}

	private Signature[] convert(Certificate[] certs)
			throws CertificateEncodingException {
		if (certs != null && certs.length>0) {			
			Signature[] sigs = new Signature[certs.length];
			sigs[0] = new Signature(certs[0].getEncoded());
			return sigs;
		} else {
			return null;
		}
	}

}
